/* ============================================================================
 Name		: Test_Console.cpp
 Author	  : 
 Copyright   : Your copyright notice

 Description : Exe source file
 ============================================================================
 */

//  Include Files  

#include "Test_Console.h"
#include <e32base.h>
#include <e32std.h>
#include <e32cons.h>			// Console
#include <f32file.h>
#include <s32file.h>
#include <CNTDB.H>
#include <CNTITEM.H>
#include <CNTFLDST.H>
#include <BADESCA.H>
#include <epos_cposlmdatabasemanager.h>
#include <epos_hposlmdatabaseinfo.h>
#include <epos_cposlandmarkparser.h>
#include <epos_cposlandmarkdatabase.h> 
#include <vcard.h>
#include <VPROP.H>
#include <S32MEM.H>
#include <favouritessession.h> 
#include <favouritesdb.h>
#include <favouritesitem.h>
#include <coecntrl.h>    // CCoeControl
#include <coemain.h>    // CCoeEnv 

//  Constants
_LIT(KWildName,"*.vcf");
_LIT(KWildNam,"*.lmx");
_LIT(KScanDir,"c:\\private\\E2FEEBBB\\");
//for Emulator
//_LIT(KScanDir,"c:\\data\\");
_LIT(KWildBk,"*.url");


//  Global Variables

//Forward declarations
LOCAL_C CDesCArrayFlat* doScanL(RFs& aSession, const TDesC& aWildName, 
        const TDesC& aScanDir);
LOCAL_C TBool doAddVCardL(const TDesC& aFileName);
LOCAL_C TBool doSearchExistingContactsL(TDesC& val, CDesCArrayFlat& aArray);
LOCAL_C void doAddLandmarkL(RFs& aSession,const TDesC& aFileName);
LOCAL_C TBool doParseVCardL(const TDesC& aFileName);
LOCAL_C void doAddBookMarkL(const TDesC& aFileName);
LOCAL_C TDesC& doParseBookMarkL(TDesC& aFile);




//  Local Functions
LOCAL_C void MainL()
	{
	//
	// add your program code here, example code below
	//
	RFs aSession;
	TBuf<100> buf;
	
	User::LeaveIfError(aSession.Connect());
	CDesCArrayFlat* aArr_name = doScanL(aSession,KWildName,KScanDir);
		
	for(TInt i=0;i<aArr_name->Count();i++)
		{
		buf.Append(KScanDir);
		buf.Append(aArr_name->operator [](i));
		TBool aFlag= doParseVCardL(buf);
		if(!aFlag)
			{
			doAddVCardL(buf);
			}
		buf.Zero();
		}
	if(aArr_name){
	aArr_name->Reset();
	delete aArr_name;
	}
	aArr_name = doScanL(aSession,KWildNam,KScanDir);
	for(TInt i=0;i<aArr_name->Count();i++)
			{
			buf.Append(KScanDir);
			buf.Append(aArr_name->operator [](i));
			doAddLandmarkL(aSession,buf);
			buf.Zero();
			}
	if(aArr_name){
	aArr_name->Reset();
	delete aArr_name;
	}
	aArr_name = doScanL(aSession,KWildBk,KScanDir);
	for(TInt i=0;i<aArr_name->Count();i++)
			{
			doAddBookMarkL(aArr_name->operator [](i));			
			}
	if(aArr_name){
	aArr_name->Reset();
	delete aArr_name;}
	aSession.Close();
	}
	
LOCAL_C void DoStartL()
	{
	// Create active scheduler (trun active objects)
	CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
	CleanupStack::PushL(scheduler);
	CActiveScheduler::Install(scheduler);

	MainL();

	// Delete active scheduler
	CleanupStack::PopAndDestroy(scheduler);
	}

//  Global Functions

GLDEF_C TInt E32Main()
	{
	// Create cleanup stack
	__UHEAP_MARK;
	CTrapCleanup* cleanup = CTrapCleanup::New();
   
	// Run application code inside TRAP harness, wait keypress when terminated
	TRAPD(mainError, DoStartL());
	if(cleanup)
	delete cleanup;
	__UHEAP_MARKEND;
	return KErrNone;
	}

// -----------------------------------------------------------------------------
// doScanL()
// Scans the directory to identify the filenames with specified wild character
// -----------------------------------------------------------------------------
LOCAL_C CDesCArrayFlat* doScanL(RFs& aSession, const TDesC& aWildName, 
        const TDesC& aScanDir)
	{	
	TFindFile file_fi(aSession);
	CDir* file_li; 
	CDesCArrayFlat* aArray = new (ELeave) CDesCArrayFlat(1);
	
	TInt error = file_fi.FindWildByDir(aWildName,aScanDir, file_li);
	
	while (error==KErrNone)
		{
		TInt i;
		for (i=0; i<file_li->Count(); i++)
			{			
			TParse fullent;
			fullent.Set((*file_li)[i].iName,& file_fi.File(),NULL);
			aArray->AppendL((*file_li)[i].iName);
			}
		delete file_li;
		error=file_fi.FindWild(file_li);
		}	
	
	return aArray;
	
	}

// -----------------------------------------------------------------------------
// doAddVCardL()
// Adds a vCard to the existing contacts
// -----------------------------------------------------------------------------
LOCAL_C TBool doAddVCardL(const TDesC& aFileName)
	{
	TBool result = EFalse;
	RFs fileSession;
	RFile file;
	User::LeaveIfError(fileSession.Connect());
	CleanupClosePushL(fileSession);

	if (file.Open(fileSession, aFileName, EFileRead) != KErrNone)
	{
	//failed to open the file
	CleanupStack::PopAndDestroy(); //fileSession
	return EFalse;
	}
	CleanupClosePushL(file);

	//open a read stream to the file
	RFileReadStream inputFileStream(file);
	CleanupClosePushL(inputFileStream);

	//Parse vcard to find if the contact exists
	
	//open the default contacts database
	CContactDatabase* contactsDb = CContactDatabase::OpenL();
	CleanupStack::PushL(contactsDb);

	//KVersitEntityUidVCard is used to identify a vCard
	TUid uid = TUid::Uid(KVersitEntityUidVCard);

	//import one or more vCards from the read stream
	CArrayPtr<CContactItem>* imported = contactsDb->ImportContactsL(uid,
			inputFileStream,
			result,
			CContactDatabase::ETTFormat);

	//caller has ownership of the array and frees allocated memory 
	imported->ResetAndDestroy();
	delete imported;

	CleanupStack::PopAndDestroy(4); //contactsDb,inputFileStream,
	//file,fileSession
		
	return result;
	}

// -----------------------------------------------------------------------------
// doSearchExistingContactsL()
// Searches the contacts to see if the contact to be added is already existing
// Name and the Tel. No. are verified
// -----------------------------------------------------------------------------
LOCAL_C TBool doSearchExistingContactsL(TDesC& val, CDesCArrayFlat& aArray)
	{
	TBool aFl(EFalse), aFl1(EFalse);
	TBool aFt(EFalse);
	
	TBuf<100> mobile(0),buf_last(0),buf_first(0);
		
	for(TInt j=0;j<aArray.Count();j++)
		{
		if(j==0)
			buf_last = aArray.operator [](j);
		if(j==1)
			buf_first = aArray.operator [](j);
		}
				
	// Open the default contacts database:
	CContactDatabase* contactsDb = CContactDatabase::OpenL();
	CleanupStack::PushL(contactsDb);
	 
	TContactIter contact_iterator(*contactsDb);
	TContactItemId contact_id;
	
	
	while( ( contact_id = contact_iterator.NextL() ) != KNullContactId)
		{
		// Get the ID of the own card and open the contact:
		CContactItem* contact_item = contactsDb->ReadContactL(contact_id);
		CleanupStack::PushL(contact_item);
	 
		CContactItemFieldSet& field_set = contact_item->CardFields();
						
		for (TInt i = 0 ; i < field_set.Count() ; i++)
			{
				CContactItemField& field = field_set[i];
				
				if (field.ContentType().ContainsFieldType(KUidContactFieldVCardMapUnusedN))
					{
					// This is general mobile processing. It will get all general mobiles in the contact list					
					mobile.Copy(field.TextStorage()->Text());
					if(mobile.Compare(buf_first)==0)
						{
						aFl=ETrue;
						}
					if(mobile.Compare(buf_last)==0)
						{
						aFl1=ETrue;
						}
					mobile.ZeroTerminate();
					//process general mobile according to application logic
					continue;				
					}
			
				if (field.ContentType().ContainsFieldType(KUidContactFieldVCardMapTEL))
					{			
					// This is general mobile processing. It will get all general mobiles in the contact list					
					mobile.Copy(field.TextStorage()->Text());
					if(mobile.Compare(val)==0)
						{
						aFt=ETrue;
						}
					//process general mobile according to application logic
					continue;				
					}
				//}
			}
		contactsDb->CloseContactL(contact_item->Id());
		CleanupStack::PopAndDestroy(contact_item); // ownCard
		}
	CleanupStack::PopAndDestroy(contactsDb);

	if(aFl && aFl1 && aFt)
		return ETrue;
	else
		return EFalse;
	}

// -----------------------------------------------------------------------------
// doAddLandmarkL()
// Adds the landmark  
// -----------------------------------------------------------------------------
LOCAL_C void doAddLandmarkL(RFs& aSession,const TDesC& aFileName)
	{
		 
	// open DB and init it, if necessary
	CPosLandmarkDatabase* db = CPosLandmarkDatabase :: OpenL();
	CleanupStack :: PushL( db );
	if( db->IsInitializingNeeded() )
	   ExecuteAndDeleteLD( db->InitializeL() );
	 
	// MIME type for import & export
	
	_LIT8( KPosMimeTypeLandmarkCollectionLmx, "application/vnd.nokia.landmarkcollection+xml" );
	// Create the parser to be used for importing landmarks
	CPosLandmarkParser* parser = CPosLandmarkParser :: NewL( KPosMimeTypeLandmarkCollectionLmx );
	CleanupStack :: PushL( parser );
	 
	// import data (batch mode)
	parser->SetInputFileL( aFileName );
	ExecuteAndDeleteLD( db->ImportLandmarksL( *parser, CPosLandmarkDatabase::EDefaultOptions ) );	

	//Landmarks with same Name are termed as duplicates and hence deleted
	CPosLmItemIterator* aIter = db->LandmarkIteratorL();
	CleanupStack::PushL(aIter);
	TPosLmItemId aLmID,aLID;
	while ((aLmID = aIter->NextL()) != KPosLmNullItemId)
		{
		TInt aCt=0;
		CPosLandmark* aLm = db->ReadLandmarkLC(aLmID);    
		TPtrC aName;
		aLm->GetLandmarkName(aName);
		CPosLmItemIterator* aIt = db->LandmarkIteratorL();
		CleanupStack::PushL(aIt);
		while ((aLID = aIt->NextL()) != KPosLmNullItemId)
			{
			CPosLandmark* aL_m = db->ReadLandmarkLC(aLID);
			TPtrC cName;
			aL_m->GetLandmarkName(cName);
			if(cName.Compare(aName)==0)
				{
				aCt++;
				if(aCt>1)
					{
					//Add code to check if the other fields are the same or not
				    //Landmark with same name and different fields might exist
					db->RemoveLandmarkL(aLID);
					}
				}
			CleanupStack::PopAndDestroy(aL_m);
			}
		CleanupStack::PopAndDestroy(1);
		CleanupStack::PopAndDestroy(aLm);
		}
	CleanupStack::PopAndDestroy(1);
	CleanupStack :: PopAndDestroy( 2); // parser db 
	}

// -----------------------------------------------------------------------------
// doParseVCardL()
// Parses the vCard for retrieving the Name and the Tel No. fields  
// -----------------------------------------------------------------------------
LOCAL_C TBool doParseVCardL(const TDesC& aFileName)
	{
	TBuf<100> buf(0), buf_last(0), buf_first(0);
	
	CDesCArrayFlat* aArr_val = new (ELeave)CDesCArrayFlat(1);
	CleanupStack::PushL(aArr_val);
	
	RFs fileSession;
	RFile file;
	User::LeaveIfError(fileSession.Connect());
	CleanupClosePushL(fileSession);

	if (file.Open(fileSession, aFileName, EFileRead) != KErrNone)
	{
	//failed to open the file
	CleanupStack::PopAndDestroy(); //fileSession
	}
	CleanupClosePushL(file);

	//open a read stream to the file
	RFileReadStream inputFileStream(file);
	CleanupClosePushL(inputFileStream);
	
	CParserVCard* vCardParser = CParserVCard::NewL();
	CleanupStack::PushL(vCardParser);
	vCardParser->InternalizeL(inputFileStream);
	
	CArrayPtr<CParserProperty>* properties = vCardParser->ArrayOfProperties(EFalse);
	CleanupStack::PushL(properties);
	for(TInt i=0;i<properties->Count();i++)
		{
		
		TPtrC8 name = properties->operator[](i)->Name();
		if(name.Match(_L8("TEL"))==KErrNone)
			{
			CParserPropertyValueHBufC* value = static_cast<CParserPropertyValueHBufC*>(properties->operator[](i)->Value());
			CleanupStack::PushL(value);
			TPtrC val_ptr = value->Value();
			buf.Copy(val_ptr);
			CleanupStack::Pop(value);
			}
		if(name.Match(_L8("N"))==KErrNone)
			{
			CParserPropertyValueCDesCArray* value = static_cast<CParserPropertyValueCDesCArray*>(properties->operator[](i)->Value());
			CleanupStack::PushL(value);
			CDesCArray* aArr = value->Value();
			for(TInt k=0;k<aArr->Count();k++)
				{
				TPtrC val = aArr->operator [](k);
				if(k==0) 
					buf_last.Copy(val);
				if(k==1)
					buf_first.Copy(val);
				}
			CleanupStack::Pop(value);
			}
		}
	CleanupStack::Pop(properties);
	file.Close();
	CleanupStack::PopAndDestroy(vCardParser);
	CleanupStack::PopAndDestroy(3);
	aArr_val->AppendL(buf_last);
	aArr_val->AppendL(buf_first);
	
	TBool aFlag = doSearchExistingContactsL(buf,*aArr_val);
	CleanupStack::Pop(aArr_val);
	return aFlag;
	}

// -----------------------------------------------------------------------------
// doAddBookMarkL()
// Adds the bookmark 
// -----------------------------------------------------------------------------
LOCAL_C void doAddBookMarkL(const TDesC& aFileName)
	{
	TBuf<100> buf, bu_url;
	RFavouritesSession iSession;
	User::LeaveIfError(iSession.Connect());
	CleanupClosePushL(iSession); 
	RFavouritesDb db;
	
	// KBrowserBookmarks is picked up from the header
	User::LeaveIfError(db.Open(iSession, KBrowserBookmarks)); 
	CleanupClosePushL(db); 
	CFavouritesItem* item =  CFavouritesItem::NewLC();
	
	if(aFileName.Length()>KFavouritesMaxName)
		{
		buf = aFileName.Mid(0,50);
		item->SetNameL(buf);
		}
	else
		item->SetNameL(aFileName);
	
	item->SetParentFolder(KFavouritesRootUid);
	item->SetType(CFavouritesItem::EItem);
	
	buf.Zero();
	buf.Append(KScanDir);
	buf.Append(aFileName);
	bu_url = doParseBookMarkL(buf);
	item->SetUrlL(bu_url); 
	User::LeaveIfError(db.Add(*item, EFalse)); 
	
	CleanupStack::PopAndDestroy(3,&iSession); // db, item
	
	}

// -----------------------------------------------------------------------------
// doParseBookMarkL()
// Parses the bookmark to retrieve the URI
// -----------------------------------------------------------------------------

LOCAL_C TDesC& doParseBookMarkL(TDesC& aFile)
	{
	RFs aFs;
	User::LeaveIfError(aFs.Connect());
	CleanupClosePushL(aFs);
	RFile aFil;
	
	HBufC8* aBuffer;
	TBuf8<100> buf_start(0), buf_end(0);
	TBuf<100> url(0);
	
	TBuf<32> bufname;
	if(aFil.Open( aFs, aFile,EFileRead )==KErrNone)
		{
		CleanupClosePushL(aFil);
		TInt FilSiz(0);		
		if(aFil.Size(FilSiz) == KErrNone)
			{
			if(FilSiz > 0)			
				{
				aBuffer = HBufC8::NewL( FilSiz );
				CleanupStack::PushL(aBuffer);
				TPtr8 ReadPoint(aBuffer->Des());			
				aFil.Read(ReadPoint,FilSiz);
				}
			}
			buf_start.Copy(_L("URL="));
			buf_end.Copy(_L("\n"));
	
			TInt pos=aBuffer->Find(buf_start);
			TInt rtLen= aBuffer->Length()-pos;
			TPtr8 ptr=aBuffer->Des().RightTPtr(rtLen);
			TInt endpos=ptr.Find(buf_end);
									
			url.Copy(aBuffer->Mid((pos+4),(endpos-4)));	
			
			CleanupStack::PopAndDestroy(aBuffer);
		}
		aFil.Close();
			
	aFs.Close();
	CleanupStack::Pop(2);
	return url;
	}



